package project.parser.tokenizer;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.NoSuchElementException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ReaderMatcher {

	private final Matcher matcher;
	private final BufferedReader buffReader;
	private String region;
	private boolean matched;
	private String skippedString;

	private void skip() {
		if (matcher.find()) {
			skippedString = region.substring(matcher.regionStart(),
					matcher.start());
			matcher.region(matcher.start(), matcher.regionEnd());
		} else {
			skippedString = region.substring(matcher.regionStart(),
					matcher.regionEnd());
			matcher.region(matcher.regionEnd(), matcher.regionEnd());
		}
	}

	public ReaderMatcher(String regex, Reader reader) {
		matcher = Pattern.compile(regex).matcher("");
		buffReader = new BufferedReader(reader);
	}

	public String getSkippedString() {
		return matched ? "" : skippedString;
	}

	public boolean nextMatches() throws IOException {
		if (!hasNext())
			throw new NoSuchElementException();
		matched = matcher.lookingAt();
		if (!matched)
			skip();
		return matched;
	}

	public String group() {
		return matcher.group();
	}

	public String group(int group) {
		return matcher.group(group);
	}

	public String group(String name) {
		return matcher.group(name);
	}

	public boolean hasNext() throws IOException {
		if (matched) {
			matcher.region(matcher.end(), matcher.regionEnd());
			matched = false;
		}
		while (matcher.regionStart() >= matcher.regionEnd()) {
			region = buffReader.readLine();
			if (region == null) {
				matcher.reset("");
				return false;
			}
			matcher.reset(region);
		}
		return true;
	}

	public static void main(String[] args) {
		ReaderMatcher rm = new ReaderMatcher("([a-zA-Z_][a-zA-Z_0-9]*)|\\s+",
				new InputStreamReader(System.in));
		try {
			while (rm.hasNext()) {
				if (rm.nextMatches()) {
					if (rm.group(1) != null)
						System.out.println("Ident: " + rm.group(1));
				} else
					System.out.println("Skipping input "
							+ rm.getSkippedString());
			}
		} catch (IOException e) {
			System.err.println(e.getMessage());
		}
	}
}
